package com.ethink.platform.manager;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.ObjectUtil;
import com.alibaba.fastjson.JSON;
import com.ethink.framework.common.constant.CommonRespCode;
import com.ethink.framework.common.exception.BusinessException;
import com.ethink.mdm.api.MateFacade;
import com.ethink.mdm.api.info.MateSkuInfo;
import com.ethink.order.api.TocSaleImportJobLogFacade;
import com.ethink.order.api.TocSaleImportLogFacade;
import com.ethink.order.api.constant.OrderRespCode;
import com.ethink.order.api.info.TocSaleImportJobLogInfo;
import com.ethink.order.api.info.TocSaleImportLogDetailInfo;
import com.ethink.order.api.info.TocSaleImportLogInfo;
import com.ethink.order.api.model.TocSaleOrderExcelModel;
import com.ethink.platform.api.constant.PlatformConstant;
import com.ethink.platform.controller.order.info.TocSaleOrderImportInfo;
import com.ethink.warehouse.api.SubWarehouseFacade;
import com.ethink.warehouse.api.enums.InventoryTypeEnum;
import com.ethink.warehouse.api.info.SubWarehouseInfo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Component;
import org.springframework.web.multipart.MultipartFile;

import java.util.List;
import java.util.Map;
import java.util.function.Function;
import java.util.stream.Collectors;

/**
 * @author default
 * @version 1.0.0
 * @ClassName TocSaleOrderManager.java
 * @Description
 * @createTime 2022年11月22日 17:57:00
 */
@Component
public class TocSaleOrderManager {

    @Autowired
    private ExcelImportManager excelImportManager;

    @Autowired
    private MateFacade mateFacade;

    @Autowired
    private SubWarehouseFacade subWarehouseFacade;

    @Autowired
    private TocSaleImportLogFacade tocSaleImportLogFacade;

    @Autowired
    private PublicManager publicManager;

    @Autowired
    private TocSaleImportJobLogFacade tocSaleImportJobLogFacade;

    @Autowired
    private AsyncManager asyncManager;

    @Autowired
    private RedisTemplate redisTemplate;

    public List<TocSaleOrderImportInfo> importTocSaleOrder(MultipartFile file) {
        List<TocSaleOrderExcelModel> tocSaleOrderExcelModels = excelImportManager.transferClass(file, TocSaleOrderExcelModel.class);
        if (CollUtil.isEmpty(tocSaleOrderExcelModels)) {
            return CollUtil.newArrayList();
        }

        List<String> mateSkuCodeList = tocSaleOrderExcelModels.stream().map(TocSaleOrderExcelModel::getMateSku).distinct().collect(Collectors.toList());
        List<MateSkuInfo> mateSkuInfoList = mateFacade.queryMateSkuBySkuCodeList(mateSkuCodeList);
        //商品编码校验
        List<String> diff = publicManager.getDiff(mateSkuCodeList, mateSkuInfoList.stream().map(MateSkuInfo::getMateSku).collect(Collectors.toList()));
        if (CollUtil.isNotEmpty(diff)) {
            throw new BusinessException(CommonRespCode.PARAM_ERR.getCode(), String.format(OrderRespCode.DIFF_MATE_SKU_1.getMessage(), JSON.toJSONString(diff)));
        }
        //网店订单号只能导入一次
        List<String> shopOrderNoList = CollUtil.getFieldValues(tocSaleOrderExcelModels, "shopOrderNo", String.class);
        List<TocSaleImportLogDetailInfo> tocSaleImportLogDetailInfos = tocSaleImportLogFacade.queryDetailByShopOrderNo(shopOrderNoList);
        if (CollUtil.isNotEmpty(tocSaleImportLogDetailInfos)) {
            throw new BusinessException(CommonRespCode.PARAM_ERR.getCode(), "网店订单号已存在,请检查数据后重新导入");
        }
        Map<String, MateSkuInfo> skuMap = mateSkuInfoList.stream().collect(Collectors.toMap(MateSkuInfo::getMateSku, Function.identity()));
        Map<String, SubWarehouseInfo> warehouseInfoMap = subWarehouseFacade.listSubWarehouse()
                .stream().collect(Collectors.toMap(SubWarehouseInfo::getSubWarehouseName, Function.identity()));
        List<TocSaleOrderImportInfo> importInfoList = tocSaleOrderExcelModels.stream().map(
                m -> {
                    TocSaleOrderImportInfo importInfo = new TocSaleOrderImportInfo();
                    importInfo.setSubWarehouseName(m.getSubWarehouseName());
                    importInfo.setOutQty(m.getOutQty());
                    importInfo.setSalePriceWb(m.getSalePriceWb());
                    importInfo.setShopOrderNo(m.getShopOrderNo());
                    importInfo.setOrderTime(m.getOrderTime());
                    importInfo.setInventoryType(InventoryTypeEnum.ZP.getIntValue());
                    BeanUtil.copyProperties(skuMap.get(m.getMateSku().trim()), importInfo);
                    SubWarehouseInfo subWarehouseInfo = warehouseInfoMap.get(m.getSubWarehouseName().trim());
                    if (ObjectUtil.isEmpty(subWarehouseInfo)) {
                        throw new BusinessException(CommonRespCode.PARAM_ERR, "仓库名称不存在: " + m.getSubWarehouseName());
                    }
                    importInfo.setSubWarehouseCode(subWarehouseInfo.getSubWarehouseCode());
                    return importInfo;
                }).collect(Collectors.toList());
        return importInfoList;
    }


    /**
     * 销售单批量处理失败日志
     *
     * @param id
     */
    public void processTocSaleImportJobLog(Long id) {
        Boolean result = redisTemplate.opsForHash().hasKey(PlatformConstant.SALE_IMPORT_LOG_ID_KEY, id.toString());
        if (result) {
            throw new BusinessException(CommonRespCode.PARAM_ERR.getCode(), "正在处理中,请稍后再试");
        }
        redisTemplate.opsForHash().put(PlatformConstant.SALE_IMPORT_LOG_ID_KEY, id.toString(), id);
        List<TocSaleImportJobLogInfo> infos = tocSaleImportJobLogFacade.queryFailureLogs(id);
        if (CollUtil.isEmpty(infos)) {
            //删除key
            redisTemplate.opsForHash().delete(PlatformConstant.SALE_IMPORT_LOG_ID_KEY, id.toString());
            throw new BusinessException(CommonRespCode.PARAM_ERR.getCode(), "无失败记录,无需处理");
        }
        TocSaleImportLogInfo main = tocSaleImportLogFacade.queryById(id);
        List<TocSaleImportLogDetailInfo> detailInfos = tocSaleImportLogFacade.queryDetailByShopOrderNo(infos.stream()
                .map(TocSaleImportJobLogInfo::getShopOrderNo).collect(Collectors.toList()));
        asyncManager.saleAdd2FailureProcess(main, detailInfos);
    }
}
